#include "common.h"

namespace common
{
    CString WinString::UTF8ToUnicode( LPCSTR pszText )
    {
        CString strText;
        if( !pszText || !*pszText )
        {
            return strText;
        }

        int len = ::MultiByteToWideChar( CP_UTF8, 0, pszText, (int)strlen( pszText ), 0, 0 );
        if( len > 0 )
        {
            WCHAR * wszText = new WCHAR[ len + 1 ];
            if( wszText && ::MultiByteToWideChar( CP_UTF8, 0, pszText, (int)strlen( pszText ), wszText, len ) != 0 )
            {
                wszText[ len ] = 0;
                strText = wszText;
            }

            if( wszText )
            {
                delete[] wszText;
            }
        }
        return strText;
    }

    CStringA WinString::UnicodeToUTF8( LPCWSTR pszwText )
    {
        CStringA strText;
        if( !pszwText || !*pszwText )
        {
            return strText;
        }

        int len = ::WideCharToMultiByte( CP_UTF8, 0, pszwText, (int)wcslen( pszwText ), 0, 0, 0, 0 );
        if( len > 0 )
        {
            CHAR * szText = new CHAR[ len + 1 ];
            if( szText && ::WideCharToMultiByte( CP_UTF8, 0, pszwText, (int)wcslen( pszwText ), szText, len, 0, 0 ) != 0 )
            {
                szText[ len ] = 0;
                strText = szText;
            }

            if( szText )
            {
                delete[] szText;
            }
        }
        return strText;
    }

    WindowDC::WindowDC()
    {
        m_dwType = DefaultDC;
        m_hDC = ::GetDC(NULL);
        m_hWnd = NULL;
    }

    WindowDC::WindowDC( HWND hWnd )
    {
        m_dwType = HandlerDC;
        m_hWnd = hWnd;
        m_hDC = ::GetDC( hWnd );
    }

    WindowDC::~WindowDC()
    {
        if( (m_dwType & DefaultDC) == DefaultDC )
        {
            ::ReleaseDC( NULL, m_hDC );
        }
        
        if( (m_dwType & HandlerDC) == HandlerDC )
        {
            ::ReleaseDC( m_hWnd, m_hDC );
        }

        m_hWnd = 0;
        m_hDC = 0;
    }

    WinMemoryDC::WinMemoryDC()
    {
        m_dwType = DefaultDC;
        m_hDC = ::GetDC( NULL );
        m_hMemDC = ::CreateCompatibleDC( m_hDC );
        m_hBitmap = NULL;
    }

    WinMemoryDC::WinMemoryDC( HDC hDC )
    {
        m_dwType = CompatibleDC;
        m_hDC = hDC;
        m_hMemDC = ::CreateCompatibleDC( m_hDC );
        m_hBitmap = NULL;
    }

    WinMemoryDC::WinMemoryDC( HBITMAP hBitmap )
    {
        m_dwType = DefaultDC | BitmapDC;
        m_hDC = ::GetDC( NULL );
        m_hMemDC = ::CreateCompatibleDC( m_hDC );
        m_hBitmap = (HBITMAP)::SelectObject( m_hMemDC, hBitmap );
    }

    WinMemoryDC::~WinMemoryDC()
    {
        if( (m_dwType & BitmapDC) == BitmapDC )
        {
            ::SelectObject( m_hMemDC, m_hBitmap );
        }

        ::DeleteDC( m_hMemDC );

        if( (m_dwType & DefaultDC) == DefaultDC )
        {
            ::ReleaseDC( NULL, m_hDC );
        }

        if( (m_dwType & CompatibleDC) == CompatibleDC )
        {
        
        }
    }

    BOOL WinHelper::CenterWindow( HWND hWnd, HWND hWndParent )
    {
        if( !hWnd )
        {
            return FALSE;
        }

        RECT rcWnd = { 0 };
        RECT rcParentWnd = { 0 };
        if( hWndParent )
        {
            ::GetWindowRect( hWndParent, &rcParentWnd ); 
        }
        else
        {
            ::SystemParametersInfo( SPI_GETWORKAREA, 0, &rcParentWnd, 0 );
        }

        ::GetWindowRect( hWnd, &rcWnd );

        int width = rcWnd.right - rcWnd.left;
        int height = rcWnd.bottom - rcWnd.top;
        int xOffset = (( rcParentWnd.right - rcParentWnd.left ) - width) / 2;
        int yOffset = (( rcParentWnd.bottom - rcParentWnd.top ) - height) / 2;

        ::SetWindowPos( hWnd, NULL, rcParentWnd.left + xOffset, rcParentWnd.top + yOffset, 0, 0, SWP_NOSIZE );
        return TRUE;
    }

    WinEvent::WinEvent()
    {
        m_hEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
    }

    WinEvent::~WinEvent()
    {
        if( m_hEvent )
        {
            ::CloseHandle( m_hEvent );
            m_hEvent = 0;
        }
    }

    void WinEvent::Set()
    {
        if( m_hEvent )
            ::SetEvent( m_hEvent );
    }

    void WinEvent::Reset()
    {
        if( m_hEvent )
            ::ResetEvent( m_hEvent );
    }

    BOOL WinEvent::Wait( DWORD dwTimeout )
    {
        if( m_hEvent )
        {
            DWORD dwWait = ::WaitForSingleObject( m_hEvent, dwTimeout );
            if( dwWait == WAIT_OBJECT_0 )
                return TRUE;
        }

        return FALSE;
    }
}